import Vue from "vue";
import Vuex from "vuex";
import SockJS from "sockjs-client";
import Stomp from "stompjs";
Vue.use(Vuex);
export default new Vuex.Store({
  state: {
    url: `${process.env.VUE_APP_API}/stomp`,
    checkInterval: null, // 断线重连时 检测连接是否建立成功
    websocket: null,
    stompClient: null,
    listenerUrlArr: [], // 所有需要订阅的url通道（包含已经订阅的和未订阅的），用于断线重连时，重新建立通道
    subscribedUrlArr: [], // 已经订阅的url通道, 避免重复订阅通道
    wsData: {}, // 订阅通道返回的数据
    reconnectNums: 0 // 失败重连次数---默认0，设置超过10次不再重连
  },
  getters: {
    wsData(state) {
      return state.wsData;
    }
  },
  mutations: {
    websocket_disconnect(state) {
      state.stompClient.disconnect(() => {
        console.log("ws结束");
      });
    },
    websocket_init(state, url) {
      console.log("进来了------------", url);
      state.url = url;
      // if (state.stompClient == null) {
      //   return this.commit("websocket_connect");
      // }
      // if (!state.stompClient.connected) {
      //   // readyState属性可以判断ws的连接状态，0：正在建立连接，1：连接已建立，2:连接正在关闭，3连接已关闭或没有建立连接
      //   if (state.websocket.readyState === 1) {
      //     //经常会遇到websocket的状态为open 但是stompClient的状态却是未连接状态，故此处需要把连接断掉 然后重连
      //     state.stompClient.disconnect(() => {
      //       this.commit("websocket_connect");
      //     });
      //   } else if (state.websocket.readyState === 3 || state.websocket.readyState === 4) {
      //     this.commit("websocket_connect");
      //   }
      // }
      // https://www.csdn.net/tags/MtTaEgysMTQxNDA1LWJsb2cO0O0O.html
      if (state.stompClient == null || !state.stompClient.connected) {
        // state.url = url;
        if (state.stompClient != null && state.websocket.readyState === SockJS.OPEN) {
          state.stompClient.disconnect(() => {
            this.commit("websocket_connect");
          });
        } else if (state.stompClient != null && state.websocket.readyState === SockJS.CONNECTING) {
          console.log("连接正在建立");
          return;
        } else {
          this.commit("websocket_connect");
        }
        if (!state.checkInterval) {
          const interval = setInterval(() => {
            console.log("检测连接：" + state.websocket.readyState);
            if (state.stompClient != null && state.stompClient.connected) {
              clearInterval(state.checkInterval);
              state.checkInterval = null;
              console.log("重连成功");
            } else if (state.stompClient != null && state.websocket.readyState != SockJS.CONNECTING) {
              // 经常会遇到websocket的状态为open 但是stompClient的状态却是未连接状态，故此处需要把连接断掉 然后重连
              state.stompClient.disconnect(() => {
                this.commit("websocket_connect");
              });
            }
          }, 2000);
          state.checkInterval = interval;
        }
      } else {
        console.log("连接已建立成功，不再执行");
      }
    },
    websocket_connect(state) {
      const _this = this;
      console.log("websocket_connect state.url", state.url);
      const websock = new SockJS(state.url);
      state.websocket = websock;
      // 获取STOMP子协议的客户端对象
      const stompClient = Stomp.over(websock);
      // stompClient.debug = null; //关闭控制台打印
      // stompClient.heartbeat.outgoing = 20000;
      // stompClient.heartbeat.incoming = 0; //客户端不从服务端接收心跳包
      // 向服务器发起websocket连接
      stompClient.connect(
        {},
        () => {
          // 连接成功时（服务器响应 CONNECTED 帧）的回调方法
          console.log('链接成功！');
          state.listenerUrlArr.forEach((listener) => {
            _this.commit('websocket_subscribe', listener);
          });
          state.reconnectNums = 0;
        },
        () => {
          // 连接失败时（服务器响应 ERROR 帧）的回调方法
          setTimeout(() => {
            console.log('nums', state.reconnectNums);
            // if (state.reconnectNums < 10) {
            console.log('失败重连！');
            _this.commit('websocket_init', state.url);
            // }
            state.reconnectNums++;
          }, 2000);
        }
      );
      state.stompClient = stompClient;
    },
    websocket_send(state, p) {
      state.stompClient.send(p.topic, {}, p.data);
    },
    // 断开ws订阅通道，清空订阅数据
    websocket_unsubscribe(state, listenerUrl) {
      state.stompClient.unsubscribe(listenerUrl);
      // 清空订阅通道返回的数据
      state.wsData = {};
      // 从所有订阅的url通道中删除当前url通道
      for (let i = 0; i < state.listenerUrlArr.length; i++) {
        if (state.listenerUrlArr[i] === listenerUrl) {
          state.listenerUrlArr.splice(i, 1);
          break;
        }
      }
      // 从成功订阅的url通道中删除当前url通道
      for (let i = 0; i < state.subscribedUrlArr.length; i++) {
        if (state.subscribedUrlArr[i] === listenerUrl) {
          state.subscribedUrlArr.splice(i, 1);
          break;
        }
      }
    },
    // 订阅ws通道
    websocket_subscribe(state, listenerUrl) {
      console.log("state", state);
      console.log("listenerUrl", listenerUrl);
      if (state.listenerUrlArr.indexOf(listenerUrl) === -1) {
        state.listenerUrlArr.push(listenerUrl);
      }
      if (state.stompClient && state.stompClient.connected) {
        if (state.subscribedUrlArr.indexOf(listenerUrl) === -1) {
          state.subscribedUrlArr.push(listenerUrl);
          state.stompClient.subscribe(listenerUrl, (msg) => {
            const res = JSON.parse(msg.body);
            // console.log("socket消息==============", res);
            res.time = new Date(); // 处理重复更新同一条数据
            state.wsData = res;
          });
        }
      } else {
        this.commit("websocket_init", listenerUrl);
        // this.commit("websocket_init", state.url);
      }
    }
  },
  actions: {
    websocket_disconnect({ commit }) {
      commit("websocket_disconnect");
    },
    websocket_init({ commit }, url) {
      commit("websocket_init", url);
    },
    websocket_send({ commit }, p) {
      commit("websocket_send", p);
    },
    websocket_unsubscribe({ commit }, listenerUrl) {
      commit("websocket_unsubscribe", listenerUrl);
    },
    websocket_subscribe({ commit }, listenerUrl) {
      commit("websocket_subscribe", listenerUrl);
    }
  }
});
